import { DefaultStage } from "../default-stage";
import { Global } from '../../data/data';
import { HUB_SCOPE, MessageHub } from "../../../../common/global/message-hub";
import { ISetupData, PREVIEW_HUB_MESSAGE_TYPE } from "../../../../common/global/preview-hub-message-type";
import { GalleryResolver } from "../../../../common/assets/gallery-resolver/gallery-resolver";
import { PhysicsManager } from "../../../../common/physics/physicsManager";
import { CharacterController, CONTROLLER_TYPE } from "../../../../common/interactive-object/character/character-controller/character-controller";
import { ArcRotateCamera, GLTFMeshTaskInfo, Vector3 } from "babylon-lib/index";
import { VirtualJoystick } from "../../../../common/interactive-object/character/character-controller/virtual-joystick";
import { RawAssetsUrl } from "../../raw-assets-info";
import { Character } from '../../../../common/interactive-object/character/character';
import { MultiplayerManager } from "../../../../common/multiplayer/client/multiplayer-manager";
import { CharacterManager } from '../../../../common/multiplayer/client/character-manager';
import { CameraAvoidBlock } from "../../../../common/interactive-object/character/character-controller/camera-avoid-block";
import { AssetManager } from "../../../../common/assets/asset-manager";


class InitializeHub {

    public static initialize(stage: DefaultStage): void {
        Global.hub = new MessageHub<PREVIEW_HUB_MESSAGE_TYPE>(window.parent, HUB_SCOPE.PREVIEW);
        this.setup(stage);

        Global.hub.dispatch(PREVIEW_HUB_MESSAGE_TYPE.IFRAME_READY, undefined);
    }

    private static setup(stage: DefaultStage): void {
        const camera = stage.mainCamera as ArcRotateCamera;

        Global.hub!.listen(PREVIEW_HUB_MESSAGE_TYPE.SETUP, (_data) => {
            const data = JSON.parse(_data.data as unknown as string) as ISetupData;
            console.log('preview setup with data+++++++++++++++++++++', data);

            CharacterManager.initialize(stage);
            // MultiplayerManager.initialize(data.room.id, data.room.serverUrl, {
            //     id: data.user.id!,
            //     name: data.user.name!,
            //     outfit: data.user.outfit!,
            //     x: 0,
            //     y: 0,
            //     z: 0,
            //     rx: 0,
            //     ry: 0,
            //     rz: 0,
            //     sx: 1,
            //     sy: 1,
            //     sz: 1,
            //     actionIndex: 0,
            //     actionLoop: false,
            //     visible: true,
            // }, stage);

            const resolve = new GalleryResolver(data.room.scene, stage, async (r) => {
                const controller = new CharacterController(camera, stage, {
                    mode: CONTROLLER_TYPE.THIRD_PERSON,
                    thirdPersonBetaUpperLimit: 3,
                    characterPosition: new Vector3(-4, 0, 0),
                });
                CharacterManager.defineController(controller);
                if (VirtualJoystick.initialized) {
                    VirtualJoystick.fromTexture = stage.loader(stage.mainScene).getTextureTaskInfo(RawAssetsUrl.textureCircle)?.texture!;
                    VirtualJoystick.toTexture = stage.loader(stage.mainScene).getTextureTaskInfo(RawAssetsUrl.textureRound)?.texture!;
                }
                const character = await Character.create(stage, {
                    id: data.user.id,
                    name: data.user.name,
                    modelUrl: data.user.outfit,
                    idleIndex: 5,
                    walkIndex: 6,
                    runIndex: 7,
                    jumpIndex: 8,
                });
                controller.setCharacter(character, new Vector3(0, -1, 0));
                CharacterManager.defineSelf(character);
                character.playAction(character.idleIndex, true);

                setTimeout(() => {
                    character.isVisible = false;
                }, 1000);
                setTimeout(() => {
                    character.isVisible = true;
                }, 2000);

                PhysicsManager.debug = controller.debug = false;

                /**
                 * test
                 */
                const CAB = new CameraAvoidBlock(camera, {
                    fixed: true,
                });
                CAB.active = true;
                const rigid = await AssetManager.fetch(data.room.scene.sceneRigidUrl!, stage.loader(stage.mainScene)) as GLTFMeshTaskInfo;
                CAB.addTargets(...rigid.loadedMeshes!);
            });

        });
    }

}


export { InitializeHub };